package com.fount4j.generator.util;

import com.fount4j.generator.constant.GeneratorConstants;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Bean 工具类
 *
 * @author Morven 2016/12/22
 */
public final class BeanUtils {

    private BeanUtils() {}

    /**
     * 创建类的实例
     *
     * @param cls 类
     * @param <T> 类的泛型
     * @return 实例对象
     * @throws IllegalAccessException e
     * @throws InstantiationException e
     */
    public static <T> T newInstance(Class<T> cls) throws IllegalAccessException, InstantiationException {
        return cls.newInstance();
    }

    /**
     * 创建类的实例对象
     *
     * @param cls 类
     * @return 实例对象
     * @throws ClassNotFoundException e
     * @throws IllegalAccessException e
     * @throws InstantiationException e
     */
    public static Object newInstance(String cls)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return Class.forName(cls).newInstance();
    }

    /**
     * 设置实体类的属性值
     *
     * @param bean  实体类对象
     * @param field 属性名
     * @param value 属性值
     * @throws NoSuchMethodException     e
     * @throws InvocationTargetException e
     * @throws IllegalAccessException    e
     */
    public static void setProperty(Object bean, String field, Object value)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if (bean == null || field == null) {
            return;
        }
        String methodName = "set" + StringUtils.firstUpper(field);
        Class<?> argType;
        if (value == null) {
            argType = Object.class;
        } else {
            argType = value.getClass();
        }
        Method method = bean.getClass().getMethod(methodName, argType);
        if (method != null) {
            method.invoke(bean, value);
        } else if (bean instanceof Map) {
            ((Map) bean).put(field, value);
        }
    }

    /**
     * 移除掉不使用的导入
     *
     * @param file    要解析的 Java 文件
     * @param imports 导入的类的集合
     */
    public static void removeUnuseImport(File file, Set<String> imports) throws IOException {
        if (!file.exists()) {
            return;
        }
        String content = GeneratorFileUtils.readFileToString(file, GeneratorConstants.GLOBAL_ENCODING);
        // 过滤掉未使用的导入
        Iterator<String> it = imports.iterator();
        while (it.hasNext()) {
            String imp = it.next();
            int dotIndex = imp.lastIndexOf('.');
            String name;
            if (dotIndex < 0) {
                name = imp;
            } else {
                name = imp.substring(dotIndex + 1);
            }
            if ("*".equals(name)) {
                // import 为 x.x.x.* 的情况暂时不支持，不做操作
                continue;
            }
            String regular = "[\\n\\r]+[ \\t]+@?((" + name + "[ \\n\\r\\t]+)|(.*\\(.*" + name + "[ \\t<]+))";
            Pattern pattern = Pattern.compile(regular);
            Matcher matcher = pattern.matcher(content);
            if (!matcher.find()) {
                it.remove();
            }
        }
    }

    /**
     * 创建导入包的 List 根据 Eclipse 包排序方式进行排序
     *
     * @param imports 全量的 import
     * @return 按照包路径区分开的 import
     */
    public static List<List<String>> createImportsList(List<String> imports) {
        List<List<String>> result = new ArrayList<>();
        if (imports == null || imports.isEmpty()) {
            return result;
        }
        // Java 中包导入的排序
        // static all other
        // 空行
        // java.*
        // 空行
        // javax.*
        // 空行
        // org.*
        // 空行
        // com.*
        // 空行
        // all other imports
        List<String> javaImps = new ArrayList<>();
        List<String> javaxImps = new ArrayList<>();
        List<String> orgImps = new ArrayList<>();
        List<String> comImps = new ArrayList<>();
        List<String> otherImps = new ArrayList<>();
        for (String imp : imports) {
            if (imp.startsWith("java.")) {
                javaImps.add(imp);
            } else if (imp.startsWith("javax.")) {
                javaxImps.add(imp);
            } else if (imp.startsWith("org.")) {
                orgImps.add(imp);
            } else if (imp.startsWith("com.")) {
                comImps.add(imp);
            } else {
                otherImps.add(imp);
            }
        }
        addUnemptyList(result, javaImps);
        addUnemptyList(result, javaxImps);
        addUnemptyList(result, orgImps);
        addUnemptyList(result, comImps);
        addUnemptyList(result, otherImps);
        return result;
    }

    /**
     * 把不空的集合排序后添加到总的集合中
     *
     * @param importsList 总的集合
     * @param imports     要处理集合
     */
    private static void addUnemptyList(List<List<String>> importsList, List<String> imports) {
        if (false == imports.isEmpty()) {
            Collections.sort(imports);
            importsList.add(imports);
        }
    }
}
